import pymongo
import requests
import time
from pprint import pprint
DB = pymongo.MongoClient('192.168.1.220',29001).aminer

class Person:

    def __init__(self,):

        if not DB.person_similar.find_one() or 'a_b' not in DB.person_similar.index_information():
            DB.person_similar.create_index([("a", pymongo.DESCENDING),("b", pymongo.DESCENDING)],unique=True,name="a_b",background=True)

        if not DB.person_ego.find_one() or 'a_b' not in DB.person_ego.index_information():
            DB.person_ego.create_index([("a", pymongo.DESCENDING),("b", pymongo.DESCENDING)],unique=True,name="a_b",background=True)


        self.headers = {'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11",
                        'Authorization':'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIyLU8yK0FXXC9oSWpUZDRQZm5rR3pXcTVwZlJBaE9qdDR4UG1IZ1NkQm95aFU2TE5BeElOb2djT3IyVVN6TE56dStiTTRUYTYrZndmOVJOblFEMVZoWkh5RXl6d2JXTUhNMTZHZz09IiwiaXNzIjoicGxheS1hbmd1bGFyLXNpbGhvdWV0dGUiLCJleHAiOjE1MDMwMTk1MzksImlhdCI6MTUwMDQyNzUzOSwianRpIjoiN2NjNmUyYjhkNDM5YWI2MTE5NjUyNDcwNjJmMjdlNmQ5NjI5Y2NkMjUyMmJiNWY5NzI3ZWIzY2E1MmRjNWY1ZWViZjJmNDdjNDMzNDhlNDAxZGUyZmZkYzhiZDM3NTM5YWYyY2JiMjhlYzdhNjBlOWUwNGEwMGZmZmRlNmQyY2YzYzRiMWQ1NzUxMjc1ZGM5YWYwYjM2MzU0ZjdkMTUxYTJiOGE0YzM5N2NlNzIxNDdhNGM3ODBlZTIxNGU1ZTE5NGQzOTg2YmY1ZDAwN2UwNTZkNmIxNTY0OGNhYjQzMzk0ZjY4MGM2MGNmN2RlMjI0MDFkNWEzOWFjOTE1M2JkYiJ9.2XiLxd5bESqqxpZasNliDL01983BxQY4h8vUIUmwx88'
            }
        
    def _save_one(self,dic,_type,_id):
        dic['_id'] = dic[_id]
        try:
            DB[_type].insert_one(dic)
        except pymongo.errors.DuplicateKeyError:
            pass

    def _save_many(self,lis,_type,_id=None):
        def fun(dic):
            dic['_id']=dic[_id]
            return dic
        if _id:
            lis = list(map(fun,lis))
        try:
            DB[_type].insert_many(lis,ordered=False)
        except pymongo.errors.BulkWriteError:
            pass

    def get_person(self,_id):
        self._summary(_id)
        self._similar(_id)
        self._ego(_id)

    def _summary(self,_id):
        url = 'https://api.aminer.org/api/person/summary/%s'%_id
        jd = self._get_page(url)

        if not jd['locks']['edit']['status']:
            if not jd['contact']['has_email'] or len(jd['contact']['bio'])<2:
                raise 'not auth' 

        self._save_one(jd,  'person_summary','id')

    def _similar(self,_id):
        url = 'https://api.aminer.org/api/person/similar/%s'%_id
        jd = self._get_page(url)
        # assert jd, jd
        relps = list(map(lambda x:{'a':_id,'b':x['id']},jd))
        if jd:
            self._save_many(relps,'person_similar')
        if relps:
            self._save_many(jd,'person_index','id')


    def _ego(self,_id):
        url = 'https://api.aminer.org/api/person/ego/%s'%_id
        jd = self._get_page(url)
        # assert jd, jd
        relps = list(map(lambda x:{'a':_id,'b':x['id'],'bole':x['bole'],'boleCode':x['boleCode'],'r':x['r'],'x':x['w']},jd['nodes']))
        # pprint(relps)
        # pprint(jd['nodes'])
        self._save_many(relps,'person_ego')
        self._save_many(jd['nodes'],'person_index','id')

    def _get_page(self,url):
        sleep = 1
        while 1:
            try:
                req = requests.get(url,headers=self.headers)
                return req.json()
            except Exception as e:
                print(e)
                time.sleep(sleep)
                sleep += 5

    def _search_person(self,term,offset=0,size=99):
        term = term.replace(' ','+')
        url = 'https://api.aminer.org/api/search/person/advanced?name=&org=&offset={offset}&size={size}&sort=relevance&term={term}'
        req = requests.get(url.format_map({'offset':offset,'size':size,'term':term}),headers=self.headers)
        jd = req.json()
        assert jd.get('status')
        return jd.get('total'),jd.get('result')

    def get_key(self,kw):
        size=99
        for i in range(99):
            sleep = 1
            offset = i*size
            while 1:
                try:
                    total,result = self._search_person(kw,offset, size)
                    time.sleep(1)
                    break
                except Exception as e:
                    print(e)
                    time.sleep(sleep)
                    sleep += 5
            for dic in result:
                dic['_id'] = dic['id']
                try:
                    DB['person_search_kw'].update_one({'_id':dic['id']},{'$set':{'result':dic},'$addToSet':{'my_key':kw}},upsert=True)
                except pymongo.errors.DuplicateKeyError:
                    pass
                
            if total<offset:
                break
        
if __name__ == '__main__':
    person = Person()
  
    for each in DB.person_search_kw.find({},{'_id':1}):
        if DB.person_summary.find_one({'_id':each['_id']}):
            continue
        print(each['_id'])
        person.get_person(each['_id'])
        time.sleep(1)


    # my_kw = ['人工智能','机器学习','深度学习','强化学习','智能机器人','聊天机器人','虚拟助理','计算机视觉','图像识别','人脸识别','文字识别','可视化搜索','指纹识别','虹膜识别','手势控制','自然语言理解','自然语言处理','文本分析','语音识别','语义网络','语义搜索','无人车','无人驾驶','自动驾驶','辅助驾驶','自动泊车','智能投顾','神经计算','神经网络','算法博弈论','知识工程','知识表示','知识图','逻辑编程','规则基系统','规则引擎','进化计算','认知计算','计算智能','超级智能','自动推理','模糊逻辑','智能代理','感知计算','Artificial intelligence','Machine learning','Deep learning','Reinforcement learning','Robots','Chatterbot','Virtual Assistant','Computer Vision','Image Recognition','Facial Recognition','text recognition','Visual Search','fingerprint recognition','Iris recognition','Gesture control','Natural language understanding','Natural language processing','Text Analytics','Voice Recognition','Semantic Web','Semantic Search','Autonomous vehicle','autopilot','self driving','ADAS','Automatic parking','robo-adviser','Neurocomputing','Neural network','计算博弈论','基于规则系统','感知计算','智能主体','知觉计算','Robotics','chat bot','face recognition','finger print recognition','NLP','TEXT ANALYSIS','Autonomous car','auto pilot','self-driving','Advanced driver assistance system','robo-advisor','Neurocomput','基于规则的系统','智能体','Robotic','Autonomous cars','auto-pilot','self drive','Advanced driver assistance system','robo adviser','Algorithmic game theory','Knowledge engineering','Knowledge representation','Knowledge graph','Logic programming','Rule-based system','Rule engine','Evolutionary computation','Cognitive computing','Computational intelligence','Superintelligence','Automated reasoning','Fuzzy logic','Intelligent agent','Perceptual computing','Autonomous vehicles','self-drive','driver assistance systems','robo advisor','Algorithmic game theor','Rule based system','Perceptual comput','driver assistance system',]
    # for kw in my_kw:
    #     print(kw)
    #     person.get_key(kw)